package com.ruoyi.central.controller.custom;

import com.ruoyi.central.domain.*;
import com.ruoyi.central.enums.MaterialStatusEnum;
import com.ruoyi.central.service.*;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Tree;
import com.ruoyi.common.utils.CollectionUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.EnumUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Classname ProcessFlowMonitoring
 * @Author: sunluquan
 * @Date: 2022/3/13 10:25
 * @Description TODO
 */
@RequestMapping("/central/processFlowMonitoring")
@RestController
public class ProcessFlowMonitoringController {

    @Autowired
    private ITopCentralProductTypeService productTypeService;

    @Autowired
    private ITopCentralProductService productService;

    @Autowired
    private ITopCentralArtProcessRunService artProcessRunService;

    @Autowired
    private ITopCentralMaterialService materialService;

    @Autowired
    private ITopCentralProcessStepRunService processStepRunService;

    @Autowired
    private ITopCentralOperationStationMaterialService operationStationMaterialService;

    @Autowired
    private ITopCentralOperationStationService operationStationService;

    /**
     * 根据产品批次编号获取产品合成树结构
     * 1.根据产品批次号获取 根产品类型
     * 2.根据 根产品类型获取产品树
     *
     * @param productBatchNo
     * @return
     */
    @GetMapping("/getTree/{productBatchNo}")
    public AjaxResult getTree(@PathVariable("productBatchNo") String productBatchNo){

        //获取 根产品类型编号
        TopCentralProduct product = productService.selectUsableByBatchNo(productBatchNo);

        Integer productTypeId = product.getTypeId();
        //获取当前产品的产品树对象
        Tree<TopCentralProductType> productTypeTree = productTypeService.productTypeTreeAll().get(productTypeId);

        return AjaxResult.success(productTypeTree);
    }

    /**
     * 根据编号获取运行工艺数据
     * @param productBatchNo
     * @return
     */
    @GetMapping("/getArtProcessRun/{productBatchNo}")
    @ResponseBody
    public AjaxResult getArtProcessRun(@PathVariable("productBatchNo") String productBatchNo){

        //获取当前产品批次的所有工艺数据
        List<TopCentralArtProcessRun> artProcessRuns = artProcessRunService.selectByProdBatchNo(productBatchNo);

        Assert.notEmpty(artProcessRuns,StringUtils.format("物料编号：{} 绑定数据不存在或不可用！",productBatchNo));

        List<Integer> activeArtProcessRunIds = artProcessRuns.stream().filter(artProcessRun -> artProcessRun.getTaskStatus().isActive())
                .map(TopCentralArtProcessRun::getId).collect(Collectors.toList());

        if(StringUtils.isNotEmpty(activeArtProcessRunIds)){
            //k artProcessRunId
            Map<Integer, TopCentralProcessStepRun> activeProcessStepRunMap = processStepRunService.selectByArtProcessRunIds(activeArtProcessRunIds);
            //将工艺下的执行工序填充至工艺对象中
            artProcessRuns.stream().filter(artProcessRun -> activeProcessStepRunMap.containsKey(artProcessRun.getId()))
                .forEach(artProcessRun->artProcessRun.setProcessStepRun(activeProcessStepRunMap.get(artProcessRun.getId())));
        }

        //k 物料编号 v 工艺执行对象
        Map<String,TopCentralArtProcessRun> artProcessRunMap = CollectionUtils.toMap(artProcessRuns,TopCentralArtProcessRun::getProdId);

        List<TopCentralMaterial> materials = materialService.selectUsableByIds(artProcessRunMap.keySet());

        //当前物料是否有绑定操作工位
        //如果有则填充至物料
        if(StringUtils.isNotEmpty(materials)){
            Set<String> materialIds  = materials.stream().filter(material -> EnumUtils.equals(MaterialStatusEnum.USE_OF_STATUS, material.getMaterialStatus()))
                    .map(TopCentralMaterial::getId).collect(Collectors.toSet());
            if(StringUtils.isNotEmpty(materialIds)){
                Map<? extends Serializable, TopCentralOperationStationMaterial> operationStationMaterialMap = operationStationMaterialService.selectAllMap();
                if(StringUtils.isNotEmpty(operationStationMaterialMap)){
                    Map<? extends Serializable, TopCentralOperationStation> operationStationMap = operationStationService.selectAllMap();
                    Map<String, TopCentralOperationStationMaterial> materialIdAndOperationStationMaterialMap = operationStationMaterialMap.values().stream().filter(operationStationMaterial -> operationStationMap.containsKey(operationStationMaterial.getOperationStationId()))
                            .collect(Collectors.toMap(TopCentralOperationStationMaterial::getMaterialId,
                                    operationStationMaterial -> {
                                        operationStationMaterial.setOperationStation(operationStationMap.get(operationStationMaterial.getOperationStationId()));
                                        return operationStationMaterial;
                                    }));
                    materials.stream().filter(material -> materialIdAndOperationStationMaterialMap.containsKey(material.getId()))
                            .forEach(material -> material.setOperationStation(materialIdAndOperationStationMaterialMap.get(material.getId()).getOperationStation()));
                }
            }
            materials.forEach(material -> {
                if(artProcessRunMap.containsKey(material.getId())){
                    artProcessRunMap.get(material.getId()).setMaterial(material);
                }
            });
        }

        return AjaxResult.success(artProcessRuns);
    }
}
